#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <stdarg.h>

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)

void itoa(unsigned int n, char * buf);
void xtoa(unsigned int n, char * buf);
int isDigit(unsigned char c);

int printf(const char *fmt, ...) {
  panic("Not implemented");
}

int vsprintf(char *out, const char *fmt, va_list ap) {
  panic("Not implemented");
}

//用于按照指定格式将数据格式化为字符串，并将结果存储在字符数组中
int sprintf(char *out, const char *fmt, ...) {
  //panic("Not implemented");
    int count = 0;
    char c;
    char *s;
    int n;
    
    char buf[65];   // 缓冲区，用于转换数字为字符串
    char digit[16]; // 缓冲区，用于处理数字位数
    
    memset(buf, 0, sizeof(buf));
    memset(digit, 0, sizeof(digit));
    
    // 定义可变参数列表
    va_list ap;
    va_start(ap, fmt);
    
    // 遍历格式字符串
    while(*fmt != '\0')
    {
      if(*fmt == '%') // 如果遇到格式指示符 %d %s
      {
        fmt++;
        switch(*fmt)
        {
          case 'd': //整型
          {
            n = va_arg(ap, int);  //va_arg获取ap参数
            if(n < 0) // 处理负数
            {
              *out++ = '-';
              n = -n;
            }
            itoa(n, buf); // 将数字转换为字符串
            memcpy(out, buf, strlen(buf)); //将转换后的字符串复制到输出字符串中
            out += strlen(buf); //更新输出字符串指针
            break;
          }    
          case 'c': //字符型
          {
            c = va_arg(ap, int);
            *out = c;
            out++;  
            break;
          }
          case 'x': /*16进制*/
          {
            n = va_arg(ap, int);
            xtoa(n, buf);
            memcpy(out, buf, strlen(buf));
            out += strlen(buf);
            break;
          }
          case 's': /*字符串*/
          {
            s = va_arg(ap, char *);
            memcpy(out, s, strlen(s));
            out += strlen(s);
            break;
          }
          case '%': /*输出%*/
          {
            *out = '%';
            out++;
            break;
          }
          default:
            break;
        }
      }
      else
      {
        *out = *fmt;
        out++; 
        if(*fmt == '\n')
        {
          ;          
        }
      }
      fmt++;
    }
    va_end(ap);

    return count;
}

/*
*功能：整型(int) 转化成 字符型(char)
*注意：不用 % / 符号的话，只能正确打印:0...9的数字对应的字符'0'...'9'
*/
void itoa(unsigned int n, char * buf)
{
  int i;
        
  if(n < 10) // 如果数字小于10
  {
    buf[0] = n + '0';
    buf[1] = '\0';
    return;
  }

  // 递归调用，将除以10的结果转换为字符串并存储到缓冲区中
  itoa(n / 10, buf);

  // 计算已经存储的字符串的长度, 
  for(i=0; buf[i]!='\0'; i++);

  //将个位数字转换为字符并存储到缓冲区中
  buf[i] = (n % 10) + '0';
        
  buf[i+1] = '\0';
}

/*
*功能：16进制字(0x) 转化成 字符型(char)
*注意：不用 % / 符号的话，只能正确打印，0...9..15的数字,对应的'0'...'9''A'...'F'
*注意：由于编译问题，这个函数，暂时由uart_sendByte_hex()函数替代
*/
void xtoa(unsigned int n, char * buf)
{
  int i;
        
  if(n < 16)
  {
    if(n < 10)
    {
      buf[0] = n + '0';
    }
    else
    {
      buf[0] = n - 10 + 'a';
    }
    buf[1] = '\0';
    return;
  }

  // 递归调用
  xtoa(n / 16, buf);
        
  for(i = 0; buf[i] != '\0'; i++);
        
  if((n % 16) < 10)
  {
    buf[i] = (n % 16) + '0';
  }
  else
  {
    buf[i] = (n % 16) - 10 + 'a';
  }
  buf[i + 1] = '\0';
}

/*
 * 判断一个字符是否数字
 */
int isDigit(unsigned char c)
{
  if (c >= '0' && c <= '9')
    return 1;
  else
    return 0;
}

int snprintf(char *out, size_t n, const char *fmt, ...) {
  panic("Not implemented");
}

int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
  panic("Not implemented");
}

#endif
